package org.chs.ts.batch.factory;

import javax.validation.constraints.NotNull;
import lombok.Getter;
import lombok.Setter;
import org.springframework.util.ClassUtils;

import java.util.HashSet;
import java.util.concurrent.ThreadFactory;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @Compay 盛唐天行
 * @Author: wuwei
 * @Censor By wuwei
 * @Sence 2023/1/5 16:57
 * @Modify 2023/1/5 16:57
 * @Description 批量处理-线程池工厂
 */
public class BatchThreadFactory implements ThreadFactory {

    /** 线程名称列号 线程安全 */
    private final AtomicInteger threadCount = new AtomicInteger(0);
    /** 线程前缀
     * -- GETTER --
     *  获取线程名称
     */
    @Getter
    private String threadNamePrefix;
    /** 线程组
     * -- GETTER --
     *  获取当前线程工厂线程组
     * -- SETTER --
     *  设置当前线程工厂线程组
     */
    @Setter
    @Getter
    private ThreadGroup threadGroup;
    /** 线程优先级
     * -- SETTER --
     *  设置此工厂 创建的线程优先级
     *
     */
    @Setter
    private int threadPriority = Thread.NORM_PRIORITY;
    /** 设置是否为守护线程
     * -- GETTER --
     *  设置这个工厂是否应该创建守护进程线程，
     *  <p>默认值为“false”
     * -- SETTER --
     *  设置这个工厂是否应该创建守护进程线程

     */
    @Setter
    @Getter
    private boolean daemon = false;

    @Setter
    @Getter
    private HashSet<Thread> sliceWorkThreads = new HashSet<>();

    /**
     * 创建线程
     *
     * @param r 线程任务
     * @return 线程
     */
    @Override
    public Thread newThread(@NotNull Runnable r) {
        // 创建线程
        Thread thread = new Thread(threadGroup, r, nextThreadName());
        thread.setPriority(threadPriority);
        thread.setDaemon(isDaemon());

        sliceWorkThreads.add(thread);

        return thread;
    }

    /**
     * 获取下一个线程名称
     */
    protected String nextThreadName() {
        return getThreadNamePrefix() + this.threadCount.incrementAndGet();
    }

    /**
     * 获取线程默认名称
     */
    protected String getDefaultThreadNamePrefix() {
        return ClassUtils.getShortName(getClass()) + "-";
    }

    // region Get & Set Method

    /**
     * 设置线程名称
     */
    public void setThreadNamePrefix(String threadNamePrefix) {
        this.threadNamePrefix = (threadNamePrefix != null ? threadNamePrefix : getDefaultThreadNamePrefix());
    }

    /*
      返回此工厂 创建的线程优先级
     */
//    public int getThreadPriority() {
//        return threadPriority;
//    }

    // endregion
}
